﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SurveillanceLib
{
    /// <summary>
    /// 所有设备的基类【抽象类】
    /// </summary>
    public abstract class DriverBase
    {
        /// <summary>
        /// 初始化SDK
        /// </summary>
        /// <param name="fDisConn">断线回调函数,参见委托:DHNetSDK.fDisConnect</param>
        /// <param name="dwUser">用户数据,没有数据请使用IntPtr.Zero</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool InitializeData(Action<int, StringBuilder, int, IntPtr> fDisConn,
            IntPtr dwUser);

        /// <summary>
        /// 设备字符编码格式[默认为:gb2312,其他字符编码请通过本函数设置]
        /// </summary>
        /// <param name="encodingString">字符编码字符串，参见MSDN中的Encoding</param>
        public abstract void SetEncoding(string encodingString);

        /// <summary>
        /// 注册用户到设备，当设备端把用户设置为复用（设备默认的用户如admin,不能设置为复用），
        /// 则使用该帐号可以多次向设备注册
        /// </summary>
        /// <param name="pchDVRIP">设备IP</param>
        /// <param name="wDVRPort">设备端口</param>
        /// <param name="pchUserName">用户名</param>
        /// <param name="pchPassword">用户密码</param>
        /// <param name="lpDeviceInfo">设备信息,属于输出参数</param>
        /// <param name="error">返回登录错误码</param>
        /// <returns>失败返回0，成功返回设备ID</returns>
        public abstract string Login(string pchDVRIP, ushort wDVRPort,
            string pchUserName, string pchPassword, out NetDeviceInfoStruct lpDeviceInfo, out int error);

        /// <summary>
        /// 注销设备用户
        /// </summary>
        /// <param name="lLoginID">设备用户登录ID:DHNetSDK.DHClient.CLIENT_Login
        /// (System.String,System.UInt16,System.String,System.String,
        /// DHNetSDK.NET_DEVICEINFO@,System.Int32@)的返回值</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool Logout(string lLoginID);

        /// <summary>
        /// 清空SDK, 释放占用的资源，在所有的SDK函数之后调用
        /// </summary>
        public abstract void CleanUp();

        /// <summary>
        /// 最后操作信息[最后操作错误和成功]
        /// </summary>
        /// <param name="pErrInfoFormatStyle">最后操作信息显示格式</param>
        /// <returns>成功返回操作信息</returns>
        public abstract string GetLastOperationInfo(string pErrInfoFormatStyle);

        /// <summary>
        /// 启动实时监视
        /// </summary>
        /// <param name="lLoginID">设备用户登录ID:DHNetSDK.DHClient.CLIENT_Login
        /// (System.String,System.UInt16,System.String,System.String,
        /// DHNetSDK.NET_DEVICEINFO@,System.Int32@)的返回值</param>
        /// <param name="nChannelID">通道ID</param>
        /// <param name="hWnd">显示容器窗口句柄</param>
        /// <returns>失败返回空，成功返回实时监视ID(实时监视句柄)</returns>
        public abstract string RealPlay(string lLoginID, int nChannelID, IntPtr hWnd);

        /// <summary>
        /// 停止实时监视
        /// </summary>
        /// <param name="lRealHandle">实时监视句柄:DHNetSDK.DHClient.CLIENT_RealPlay
        /// (System.Int32,System.Int32,System.IntPtr)的返回值</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool StopRealPlay(string lRealHandle);

        /// <summary>
        /// 开始流数据录像。只对流模式有用，在 PLAY_Play 之后调用
        /// </summary>
        /// <param name="nPort">播放器通道号</param>
        /// <param name="sFileName">录像文件名，如果文件名中有不存在的文件夹，就创建该文件夹</param>
        /// <param name="idataType">0:原始数据流;1:AVI</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool StartDataRecord(int nPort, string sFileName, int idataType);

        /// <summary>
        /// 停止流数据录像
        /// </summary>
        /// <param name="nPort">播放器通道号</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool StopDataRecord(int nPort);

        /// <summary>
        /// 云台控制
        /// </summary>
        /// <param name="lLoginID">设备用户登录ID:DHNetSDK.DHClient.CLIENT_Login(System.String,System.UInt16,System.String,System.String,DHNetSDK.NET_DEVICEINFO@,System.Int32@)的返回值</param>
        /// <param name="nChannelID">通道号</param>
        /// <param name="dwPTZCommand">云台控制命令PTZControlType[PTZ_****的命令]</param>
        /// <param name="dwStep">步进/速度</param>
        /// <param name="dwStop">是否停止</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool PTZControl(string lLoginID, int nChannelID,
            string dwPTZCommand, ushort dwStep, bool dwStop);

        /// <summary>
        /// 保存图片，对显示图像进行瞬间抓图，只有打开图像的函数参数hWnd有效时该函数获取的参数才有效，否则无意义
        /// </summary>
        /// <param name="lPlayHandle">CLIENT_RealPlay的返回值</param>
        /// <param name="phPicFileName">位图文件名，当前只支持BMP位图</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool CapturePicture(string lPlayHandle, string phPicFileName);

        /// <summary>
        /// 查询录像文件
        /// </summary>
        /// <param name="lLoginID">设备用户登录句柄</param>
        /// <param name="nChannelId">通道ID</param>
        /// <param name="nRecordFileType">录像文件类型</param>
        /// <param name="tmStart">录像开始时间</param>
        /// <param name="tmEnd">录像结束时间</param>
        /// <param name="pchCardid">卡号,只针对卡号查询有效，其他情况下可以填NULL</param>
        /// <param name="nriFileinfo">返回的录像文件信息，是一个NET_RECORDFILE_INFO结构数组[录像文件信息为指定条]</param>
        /// <param name="maxlen">nriFileinfo缓冲的最大长度;[单位字节，大小为结构数组维数*sizeof(NET_RECORDFILE_INFO),数组维为大小等于1，建议小于２００]</param>
        /// <param name="filecount">返回的文件个数,属于输出参数最大只能查到缓冲满为止的录像记录</param>
        /// <param name="waittime">等待时间</param>
        /// <param name="bTime">是否按时间查(目前无效)</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool QueryRecordFile(string lLoginID, int nChannelId,
            string nRecordFileType, DateTime tmStart, DateTime tmEnd,
            string pchCardid, ref NetRecordFileInfoStruct[] nriFileinfo,
            int maxlen, out int filecount, int waittime, bool bTime);

        /// <summary>
        /// 按文件下载录像文件, 通过查询到的文件信息下载
        /// </summary>
        /// <param name="lLoginID">CLIENT_Login的返回值</param>
        /// <param name="lpRecordFile">录像文件信息</param>
        /// <param name="sSavedFileName">要保存的录像文件名，全路径</param>
        /// <param name="cbDownLoadPos">下载进度回调函数</param>
        /// <param name="dwUserData">下载进度回调用户自定义数据</param>
        /// <returns>成功返回下载ID，失败返回空</returns>
        public abstract string DownloadByRecordFile(string lLoginID, NetRecordFileInfoStruct lpRecordFile,
            string sSavedFileName, Action<int, uint, uint, IntPtr> cbDownLoadPos, IntPtr dwUserData);

        /// <summary>
        /// 停止下载录像文件
        /// </summary>
        /// <param name="lFileHandle">CLIENT_DownloadByRecordFile的返回值</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool StopDownload(string lFileHandle);

        /// <summary>
        /// 录像文件转换成AVI格式
        /// </summary>
        /// <param name="nPort">通道号</param>
        /// <param name="filename">要保存的文件名，全路径</param>
        /// <param name="pAVIFunc">文件转换回调函数</param>
        /// <param name="pUserData">回调用户自定义数据</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool StartAVIConvert(int nPort, string filename,
            Action<int, int, int, bool, string> pAVIFunc, int pUserData);

        /// <summary>
        /// 停止转换AVI录像文件
        /// </summary>
        /// <param name="nPort">通道号</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool StopAVIConvert(int nPort);

        /// <summary>
        /// 播放控制
        /// </summary>
        /// <param name="pPlayCom">播放命令: 1.PLAY_COMMAND.StopSound:停止声音</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool PlayControl(string pPlayCom);

        /// <summary>
        /// 播放控制
        /// </summary>
        /// <param name="pPlayCom">播放命令: 1.PLAY_COMMAND.Stop:停止; 2.PLAY_COMMAND.CloseFile:关闭文件; 3.PLAY_COMMAND.Pause:暂停播放;
        ///     4.PLAY_COMMAND.ReSume:继续播放; 5.PLAY_COMMAND.Fast:快放; 6.PLAY_COMMAND.Slow:慢放;
        ///     7.PLAY_COMMAND.OneByOne:单帧播放; 8.PLAY_COMMAND.PlaySound:播放声音; 9.PLAY_COMMAND.PlaySoundShare:共享播放声音;
        ///     10.PLAY_COMMAND.StopSoundShare:停止共享播放声音; 11.PLAY_COMMAND.OneByOneBack:单帧回放
        ///     12.PLAY_COMMAND.CloseStream:关闭数据流 13.PLAY_COMMAND.CloseStreamEx:关闭数据流(音视频分开方式打开流)</param>
        /// <param name="nPort">播放通道号</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool PlayControl(string pPlayCom, int nPort);

        /// <summary>
        /// 播放控制
        /// </summary>
        /// <param name="pPlayCom">播放命令: 1.PLAY_COMMAND.OpenFile:打开文件; 2.PLAY_COMMAND.CatchPic:抓图;</param>
        /// <param name="nPort">播放通道号</param>
        /// <param name="sFileName">打开/保存文件名</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool PlayControl(string pPlayCom, int nPort, string sFileName);

        /// <summary>
        /// 播放控制
        /// </summary>
        /// <param name="pPlayCom">播放命令: 1.PLAY_COMMAND.Start:开始播放</param>
        /// <param name="nPort">播放通道号</param>
        /// <param name="hWnd">播放容器句柄</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool PlayControl(string pPlayCom, int nPort, IntPtr hWnd);

        /// <summary>
        /// 播放控制
        /// </summary>
        /// <param name="pPlayCom">播放命令: 1.PLAY_COMMAND.OpenStream:打开流接口 2.PLAY_COMMAND.OpenStreamEx:以音视频分开输入的方式打开流</param>
        /// <param name="nPort">通道号</param>
        /// <param name="pFileHeadBuff">目前不使用，填NULL</param>
        /// <param name="nSize">目前不使用，填0</param>
        /// <param name="nBufPoolSize">设置播放器中存放数据流的缓冲区大小。 范围是SOURCE_BUF_MIN~ SOURCE_BUF_MAX。 一般设为900*1024，如果数据送过来相对均匀，可调小该值，如果数据传输不均匀，可增大该值</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool PlayControl(string pPlayCom, int nPort, IntPtr pFileHeadBuff,
            uint nSize, uint nBufPoolSize);

        /// <summary>
        /// 设置流播放的模式。必须在播放之前设置
        /// </summary>
        /// <param name="nPort">播放器通道号</param>
        /// <param name="nMode">数据流播放模式: 0.PLAY_MODE.STREAME_REALTIME:最实时方式 1.PLAY_MODE.STREAME_FILE:最流畅方式</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool SetStreamOpenMode(int nPort, string nMode);

        /// <summary>
        /// 回放播放控制:播放，暂停，停止，单步播放，单步停止，慢放，快放
        /// </summary>
        /// <param name="lPlayHandle">播放句柄</param>
        /// <param name="pPlayCommand">控制命令:参见PlayControlType</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool PlayBackControl(string lPlayHandle, string pPlayCommand);

        /// <summary>
        /// 回放播放控制:改变位置播放[即拖动播放，只有打开图像的函数参数hWnd有效时该函数获取的参数才有效，否则无意义]
        /// </summary>
        /// <param name="lPlayHandle">播放句柄</param>
        /// <param name="pPlayCommand">播放命令:SeekByBit,SeekByTime</param>
        /// <param name="offset">SeekByTime:相对文件开始处偏移时间,单位为秒;SeekByBit:相对文件开始处偏移字节;</param>
        /// <returns>true:成功;false:失败</returns>
        public abstract bool PlayBackControl(string lPlayHandle, string pPlayCommand, uint offset);

        /// <summary>
        /// 网络回放[注意:用户登录一台设备后，每通道同一时间只能播放一则录像,不能同时播放同一通道的多条记录]
        /// </summary>
        /// <param name="lLoginID">设备用户登录句柄</param>
        /// <param name="lpRecordFile">录像文件信息, 当按时间播放是只需填充起始时间和结束时间, 其他项填0</param>
        /// <param name="hWnd">回放容器句柄</param>
        /// <param name="cbDownLoadPos">进度回调函数</param>
        /// <param name="dwUserData">用户自定义数据</param>
        /// <returns>成功返回网络回放ID，失败返回空</returns>
        public abstract string PlayBackByRecordFile(string lLoginID, ref NetRecordFileInfoStruct lpRecordFile,
            IntPtr hWnd, Action<int, uint, uint, IntPtr> cbDownLoadPos, IntPtr dwUserData);

        /// <summary>
        /// 带数据回调的按录像文件回放扩展接口,每通道同一时间只能播放一则录像,不能同时播放同一通道的多条记录。
        /// 窗口参数（hWnd）有效时回调数据的返回值将被忽略，窗口参数(hWnd)为0时，需要注意回调函数的返回值，具体见回调函数说明。
        /// </summary>
        /// <param name="lLoginID">CLIENT_Login的返回值</param>
        /// <param name="lpRecordFile">录像文件信息</param>
        /// <param name="hWnd">回放容器句柄</param>
        /// <param name="cbDownLoadPos">进度回调函数</param>
        /// <param name="dwPosUser">进度回调函数用户数据</param>
        /// <param name="fDownLoadDataCallBack">数据回调函数</param>
        /// <param name="dwDataUser">数据回调函数用户数据</param>
        /// <returns>成功返回网络回放ID，失败返回空</returns>
        public abstract string PlayBackByRecordFile(string lLoginID, ref NetRecordFileInfoStruct lpRecordFile,
            IntPtr hWnd, Action<int, uint, uint, IntPtr> cbDownLoadPos, IntPtr dwPosUser,
            Action<int, uint, IntPtr, uint, uint> fDownLoadDataCallBack, IntPtr dwDataUser);
    }
}
